import Vue from "vue";

// eslint-disable-next-line func-names
const debounce = function (func, delay) {
  let timer = null;
  // eslint-disable-next-line func-names
  return function () {
    if (timer) clearTimeout(timer);
    timer = null;
    const self = this;
    // eslint-disable-next-line prefer-rest-params
    const args = arguments;
    timer = setTimeout(() => {
      func.apply(self, args);
    }, delay);
  };
};
Vue.directive("loadMore", {
  bind(el, binding, vnode) {
    const { expand } = binding.modifiers;
    if (expand) {
      /**
         * target 目标DOM节点的类名
         * distance 减少触发加载的距离阈值，单位为px
         * func 触发的方法
         * delay 防抖时延，单位为ms
         * load-more-disabled 是否禁用无限加载
         */
      const {
        target, distance = 0, func, delay = 300
      } = binding.value;
      if (typeof target !== "string") return;
      const targetEl = el.querySelector(target);
      if (!targetEl) {
        console.log("找不到容器");
        return;
      }
      // eslint-disable-next-line no-param-reassign
      binding.handler = debounce(() => {
        const { scrollTop, scrollHeight, clientHeight } = targetEl;
        let disabled = el.getAttribute("load-more-disabled");
        disabled = vnode[disabled] || disabled;

        if (scrollHeight <= scrollTop + clientHeight + distance) {
          if (disabled) return;
          func();
        }
      }, delay);
      targetEl.addEventListener("scroll", binding.handler);
    } else {
      // eslint-disable-next-line no-param-reassign
      binding.handler = debounce(() => {
        const { scrollTop, scrollHeight, clientHeight } = el;
        if (scrollHeight === scrollTop + clientHeight) {
          binding.value();
        }
      }, 200);
      el.addEventListener("scroll", binding.handler);
    }
  },
  unbind(el, binding) {
    // 清除
    const { arg } = binding;
    if (arg === "expand") {
      const { target } = binding.value;
      if (typeof target !== "string") return;
      let targetEl = el.querySelector(target);
      targetEl.removeEventListener("scroll", binding.handler);
      targetEl = null;
    } else {
      el.removeEventListener("scroll", binding.handler);
      // eslint-disable-next-line no-param-reassign
      el = null;
    }
  }
});
